package com.ccl.iot.privates;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.SparseArray;

import com.ccl.iot.publics.FileSystem;

public class BitmapBuilder {
	private static SparseArray<Rect> gBitmapRectColl = null;

	public synchronized static Rect GetBitmapRect(Context aContext, int aBitmap) {
		Rect tRect;

		if (gBitmapRectColl == null || (tRect = gBitmapRectColl.get(aBitmap)) == null) {
			float tScale;
			BitmapFactory.Options tOP = new BitmapFactory.Options();

			tOP.inJustDecodeBounds = true;

			BitmapFactory.decodeResource(aContext.getResources(), aBitmap, tOP);

			tScale = tOP.inTargetDensity;
			tScale /= tOP.inDensity;

			tRect = new Rect(0, 0, (int) (tOP.outWidth * tScale), (int) (tOP.outHeight * tScale));

			if (gBitmapRectColl == null) {
				gBitmapRectColl = new SparseArray<Rect>();
			}

			gBitmapRectColl.append(aBitmap, tRect);
		}

		return new Rect(tRect);
	}

	public static Bitmap GetBitmap(Drawable aDrawable) {
		if (aDrawable != null) {
			Bitmap tBitmap = Bitmap.createBitmap(aDrawable.getIntrinsicWidth(), aDrawable.getIntrinsicHeight(), aDrawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_4444
					: Bitmap.Config.RGB_565);

			Canvas tCanvas = new Canvas(tBitmap);

			aDrawable.setBounds(0, 0, aDrawable.getIntrinsicWidth(), aDrawable.getIntrinsicHeight());
			aDrawable.draw(tCanvas);

			tCanvas.save();
			tCanvas.restore();

			return tBitmap;
		}

		return null;
	}

	public static Bitmap GetBitmap(Context aContext, int aBitmap) {
		if (aContext != null) {
			BitmapFactory.Options tmpOP = new BitmapFactory.Options();
			tmpOP.inSampleSize = 1;
			tmpOP.inDither = false;
			tmpOP.inPurgeable = true;

			return BitmapFactory.decodeResource(aContext.getResources(), aBitmap, tmpOP);
		}

		return null;
	}

	public static Bitmap GetBitmap(Context aContext, int aBitmap, boolean aIsAnimation) {
		if (aContext != null) {
			if (aIsAnimation) {
				return GetBitmap(aContext.getResources().getDrawable(aBitmap));
			} else {
				return GetBitmap(aContext, aBitmap);
			}
		}

		return null;
	}

	public static Bitmap GetBitmap(Context aContext, int aBitmap, int aWidth, int aHeight) {
		if (aWidth > 0 && aHeight > 0) {
			BitmapFactory.Options tOP = new BitmapFactory.Options();

			tOP.inJustDecodeBounds = true;

			BitmapFactory.decodeResource(aContext.getResources(), aBitmap, tOP);
			if (tOP.outWidth != 0 && tOP.outHeight != 0) {
				Bitmap tBitmap;

				tOP.inPurgeable = true;
				tOP.inInputShareable = true;
				tOP.inJustDecodeBounds = false;
				if (tOP.outWidth > aContext.getResources().getDisplayMetrics().widthPixels || tOP.outHeight > aContext.getResources().getDisplayMetrics().heightPixels) {
					tOP.inSampleSize = ComputeSampleSize(tOP, -1, aWidth * aHeight);
				} else {
					tOP.inSampleSize = 1;
				}

				try {
					if ((tBitmap = BitmapFactory.decodeResource(aContext.getResources(), aBitmap, tOP)) != null) {
						if (tBitmap.getWidth() != aWidth || tBitmap.getHeight() != aHeight) {
							return Bitmap.createScaledBitmap(tBitmap, aWidth, aHeight, true);
						}
					}
				} catch (OutOfMemoryError e) {
					return null;
				}

				return tBitmap;
			}
		}

		return null;
	}

	public static Bitmap GetBitmap(String aBitmap) {
		if (aBitmap != null) {
			BitmapFactory.Options tmpOP = new BitmapFactory.Options();
			tmpOP.inSampleSize = 1;
			tmpOP.inDither = false;
			tmpOP.inPurgeable = true;
			tmpOP.inTempStorage = new byte[64 * 1024];

			File tmpFile = new File(aBitmap);
			if (tmpFile.exists()) {
				FileInputStream tFS = null;

				try {
					tFS = new FileInputStream(tmpFile);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}

				if (tFS != null) {
					try {
						Bitmap tBitmap = BitmapFactory.decodeFileDescriptor(tFS.getFD(), null, tmpOP);

						return tBitmap;
					} catch (OutOfMemoryError e) {
					} catch (IOException e) {
					}
				}
			}
		}

		return null;
	}

	private static int ComputeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;

		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));

		if (upperBound < lowerBound) {
			// return the larger one when there is no overlapping zone.
			return lowerBound;
		}

		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
			return 1;
		} else if (minSideLength == -1) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}

	private static int ComputeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
		int initialSize = ComputeInitialSampleSize(options, minSideLength, maxNumOfPixels);
		int roundedSize;

		if (initialSize <= 8) {
			roundedSize = 1;
			while (roundedSize < initialSize) {
				roundedSize <<= 1;
			}
		} else {
			roundedSize = (initialSize + 7) / 8 * 8;
		}

		return roundedSize;
	}

	public static Bitmap GetBitmap(Bitmap aBitmap, int aWidth, int aHeight, boolean aCenter) {
		if (aBitmap != null && aWidth > 0 && aHeight > 0) {

			int tWidth = aBitmap.getWidth();
			int tHeight = aBitmap.getHeight();
			int tLeft, tTop, tRight, tBottom;
			Bitmap tBitmap = Bitmap.createBitmap(aWidth, aHeight, aBitmap.getConfig());
			Canvas tCanvas = new Canvas(tBitmap);

			if (aCenter) {
				float tViewScale = (float) aWidth / (float) aHeight;
				float tBmpScale = (float) tWidth / (float) tHeight;

				if (tViewScale < tBmpScale) {
					tLeft = 0;
					tRight = aWidth;
					tBottom = (int) (tHeight * ((float) aWidth / (float) tWidth));
					tTop = (aHeight - tBottom) / 2;
					tBottom += tTop;
				} else {
					tTop = 0;
					tBottom = aHeight;
					tRight = (int) (tWidth * ((float) aHeight / (float) tHeight));
					tLeft = (aWidth - tRight) / 2;
					tRight += tLeft;
				}
			} else {
				tLeft = 0;
				tTop = 0;
				tRight = aWidth;
				tBottom = aHeight;
			}

			tCanvas.drawBitmap(aBitmap, new Rect(0, 0, tWidth, tHeight), new Rect(tLeft, tTop, tRight, tBottom), new Paint());
			tCanvas.save();
			tCanvas.restore();

			return tBitmap;
		}

		return null;
	}

	public static Bitmap GetBitmap(String aBitmap, int aWidth, int aHeight) {
		if (aBitmap != null && aWidth > 0 && aHeight > 0) {
			File tmpFile = new File(aBitmap);
			if (tmpFile.exists()) {
				FileInputStream tFS = null;

				try {
					tFS = new FileInputStream(tmpFile);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}

				if (tFS != null) {
					try {
						BitmapFactory.Options tOP = new BitmapFactory.Options();

						tOP.inJustDecodeBounds = true;
						BitmapFactory.decodeFileDescriptor(tFS.getFD(), null, tOP);

						if (tOP.outWidth != 0 && tOP.outHeight != 0) {
							Bitmap tBitmap;

							tOP.inSampleSize = ComputeSampleSize(tOP, -1, aWidth * aHeight);

							tOP.inPurgeable = true;
							tOP.inInputShareable = true;
							tOP.inJustDecodeBounds = false;

							if ((tBitmap = BitmapFactory.decodeFileDescriptor(tFS.getFD(), null, tOP)) != null) {
								float tWidthScale, tHeightScale;
								Paint tPaint = new Paint();
								Canvas tCanvas = null;
								Bitmap tFinalBitmap = null;
								Rect tSrcRect = new Rect(0, 0, tOP.outWidth, tOP.outHeight);

								tPaint.setAntiAlias(true);
								tPaint.setFilterBitmap(true);

								tFinalBitmap = Bitmap.createBitmap(aWidth, aHeight, Config.ARGB_4444);
								tCanvas = new Canvas(tFinalBitmap);

								tWidthScale = aWidth;
								tWidthScale /= tOP.outWidth;
								tHeightScale = aHeight;
								tHeightScale /= tOP.outHeight;
								if (tWidthScale < tHeightScale) {
									tSrcRect.bottom = tOP.outHeight;
									tSrcRect.left = (int) ((tOP.outWidth - (aWidth / tHeightScale)) / 2);
									tSrcRect.right = (int) (tSrcRect.left + aWidth / tHeightScale);
								} else if (tWidthScale > tHeightScale) {
									tSrcRect.right = tOP.outWidth;
									tSrcRect.top = (int) ((tOP.outHeight - (aHeight / tWidthScale)) / 2);
									tSrcRect.bottom = (int) (tSrcRect.top + aHeight / tWidthScale);
								}

								tCanvas.drawBitmap(tBitmap, tSrcRect, new Rect(0, 0, aWidth, aHeight), tPaint);

								tCanvas.save();
								tCanvas.restore();

								return tFinalBitmap;
							}
						}
					} catch (Exception e) {
					}
				}
			}
		}

		return null;
	}

	public static Bitmap MixBitmap(int aWidth, int aHeight, int aBackColor, Bitmap aBitmap, float aLeft, float aTop) {
		if (aBitmap != null && aWidth > 0 && aHeight > 0) {
			Bitmap tBitmap = null;

			tBitmap = Bitmap.createBitmap(aWidth, aHeight, aBackColor == Color.TRANSPARENT ? Config.ARGB_4444 : Config.RGB_565);
			if (aBackColor != Color.TRANSPARENT) {
				Canvas tCanvas = new Canvas(tBitmap);

				tCanvas.drawColor(aBackColor);

				tCanvas.save();
				tCanvas.restore();
			}

			return MixBitmap(tBitmap, aBitmap, aLeft, aTop);
		}

		return null;
	}

	public static Bitmap MixBitmap(Bitmap aBitmap1, Bitmap aBitmap2, float aLeft, float aTop) {
		if (aBitmap1 != null && aBitmap2 != null) {
			Bitmap tBig, tSmall;
			Canvas tCanvas;

			if (aBitmap1.getWidth() > aBitmap2.getWidth() || aBitmap1.getHeight() > aBitmap2.getHeight()) {
				tBig = aBitmap1;
				tSmall = aBitmap2;
			} else {
				tBig = aBitmap2;
				tSmall = aBitmap1;
			}

			tCanvas = new Canvas(tBig);

			if (tCanvas != null) {
				tCanvas.drawBitmap(tSmall, aLeft, aTop, new Paint());

				tCanvas.save();
				tCanvas.restore();

				return tBig;
			}
		}

		return aBitmap1;
	}

	public static Bitmap AdjustBitmapSaturation(Bitmap aBitmap, float aSaturation) {
		if (aBitmap != null) {
			Bitmap tBitmap = Bitmap.createBitmap(aBitmap.getWidth(), aBitmap.getHeight(), Bitmap.Config.ARGB_4444);
			Canvas tCanvas = new Canvas(tBitmap);
			Paint tPaint = new Paint();
			ColorMatrix tColorMatrix = new ColorMatrix();

			tColorMatrix.setSaturation(aSaturation);
			tPaint.setColorFilter(new ColorMatrixColorFilter(tColorMatrix));

			tCanvas.drawBitmap(aBitmap, 0, 0, tPaint);

			tCanvas.save();
			tCanvas.restore();

			return tBitmap;
		}

		return null;
	}

	public static boolean SaveBitmap(String aSource, String aDest, CompressFormat aType, int aQuality) {
		Bitmap tBitmap = GetBitmap(aSource);

		if (tBitmap != null && FileSystem.FileExists(aDest, true)) {
			File tDest = new File(aDest);

			try {
				return tBitmap.compress(aType, aQuality, new FileOutputStream(tDest));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		return false;
	}

	public static float GetAdjustSwitchLevel(float aYPoint, int aWidth, int aHeight) {
		float tSlipTop, tSlipBottom;

		tSlipTop = aHeight * 0.3f;
		tSlipBottom = aHeight * 0.7f;

		if (aYPoint <= tSlipTop) {
			return 1;
		} else if (aYPoint >= tSlipBottom) {
			return 0;
		} else {
			return 1 - (aYPoint - tSlipTop) / (tSlipBottom - tSlipTop);
		}
	}

	public static Bitmap GetAdjustSwitch(float aLevel, int aWidth, int aHeight) {
		float tWScale;
		float tXCorner, tYCorner;
		float tSlipTop;
		RectF tRect = new RectF();

		if (aLevel > 1) {
			aLevel = 0;
		} else {
			aLevel = 1 - aLevel;
		}

		tWScale = (aWidth / (aHeight * 0.5f));

		tXCorner = aHeight * 0.05f * tWScale;
		tYCorner = aHeight * 0.05f;

		tSlipTop = aHeight * 0.1f + aHeight * 0.4f * aLevel;

		Paint tPaint = new Paint();
		Canvas tCanvas = null;
		Bitmap tBitmap = null;

		tPaint.setAntiAlias(true);
		tPaint.setFilterBitmap(true);

		tBitmap = Bitmap.createBitmap(aWidth, aHeight, Config.ARGB_4444);
		tCanvas = new Canvas(tBitmap);

		tRect.set(1, 1, aWidth - 1, aHeight - 1);
		tPaint.setColor(Color.LTGRAY);
		tPaint.setStyle(Paint.Style.FILL);
		tCanvas.drawRoundRect(tRect, tXCorner, tYCorner, tPaint);

		tPaint.setColor(Color.BLACK);
		tPaint.setStyle(Paint.Style.STROKE);
		tCanvas.drawRoundRect(tRect, tXCorner, tYCorner, tPaint);

		tRect.set(aHeight * 0.1f * tWScale, aHeight * 0.1f, aHeight * 0.4f * tWScale, aHeight * 0.9f);
		tPaint.setStyle(Paint.Style.FILL);
		tPaint.setColor(Color.rgb(0, (int) (255 - 255 * aLevel), 0));
		tCanvas.drawRoundRect(tRect, tXCorner, tYCorner, tPaint);

		tPaint.setColor(Color.BLACK);
		tPaint.setStyle(Paint.Style.STROKE);
		tCanvas.drawRoundRect(tRect, tXCorner, tYCorner, tPaint);

		tRect.set(aHeight * 0.05f * tWScale, tSlipTop, aHeight * 0.45f * tWScale, tSlipTop + aHeight * 0.4f);
		tPaint.setColor(Color.GRAY);
		tPaint.setStyle(Paint.Style.FILL);
		tCanvas.drawRoundRect(tRect, tXCorner, tYCorner, tPaint);

		tPaint.setColor(Color.BLACK);
		tPaint.setStyle(Paint.Style.STROKE);
		tCanvas.drawRoundRect(tRect, tXCorner, tYCorner, tPaint);

		if (aLevel > 0.5) {
			tRect.set(aHeight * 0.15f * tWScale, tSlipTop + aHeight * 0.175f, aHeight * 0.35f * tWScale, tSlipTop + aHeight * 0.225f);
			tPaint.setColor(Color.rgb(255, 255, (int) (255 * aLevel)));
			tPaint.setStyle(Paint.Style.FILL);
			tCanvas.drawRoundRect(tRect, tXCorner, tYCorner, tPaint);

			tPaint.setColor(Color.BLACK);
			tPaint.setStyle(Paint.Style.STROKE);
			tCanvas.drawRoundRect(tRect, tXCorner, tYCorner, tPaint);
		} else {
			tPaint.setColor(Color.rgb(255, 255, (int) (255 * aLevel)));
			tPaint.setStyle(Paint.Style.FILL);
			tCanvas.drawCircle(aHeight * 0.25f * tWScale, tSlipTop + aHeight * 0.2f, aHeight * 0.1f * (tWScale > 1 ? 1 : tWScale), tPaint);

			tPaint.setColor(Color.BLACK);
			tPaint.setStyle(Paint.Style.STROKE);
			tCanvas.drawCircle(aHeight * 0.25f * tWScale, tSlipTop + aHeight * 0.2f, aHeight * 0.1f * (tWScale > 1 ? 1 : tWScale), tPaint);

			tPaint.setColor(Color.GRAY);
			tPaint.setStyle(Paint.Style.FILL);
			tCanvas.drawCircle(aHeight * 0.25f * tWScale, tSlipTop + aHeight * 0.2f, aHeight * 0.05f * (tWScale > 1 ? 1 : tWScale), tPaint);

			tPaint.setColor(Color.BLACK);
			tPaint.setStyle(Paint.Style.STROKE);
			tCanvas.drawCircle(aHeight * 0.25f * tWScale, tSlipTop + aHeight * 0.2f, aHeight * 0.05f * (tWScale > 1 ? 1 : tWScale), tPaint);
		}

		tCanvas.save();
		tCanvas.restore();

		return tBitmap;
	}

	public static Bitmap GetDigitalWord(char aWord, int aHeight, int aHighColor, int aShadeColor, int aBackColor) {
		int tColor[] = null;

		switch (aWord) {
		case 0:
		case '0':
		case 'o':
		case 'O': {
			tColor = new int[] { aHighColor, aHighColor, aHighColor, aShadeColor, aHighColor, aHighColor, aHighColor };
			break;
		}
		case 1:
		case '1': {
			tColor = new int[] { aShadeColor, aShadeColor, aHighColor, aShadeColor, aShadeColor, aHighColor, aShadeColor };
			break;
		}
		case 2:
		case '2': {
			tColor = new int[] { aHighColor, aShadeColor, aHighColor, aHighColor, aHighColor, aShadeColor, aHighColor };
			break;
		}
		case 3:
		case '3': {
			tColor = new int[] { aHighColor, aShadeColor, aHighColor, aHighColor, aShadeColor, aHighColor, aHighColor };
			break;
		}
		case 4:
		case '4': {
			tColor = new int[] { aShadeColor, aHighColor, aHighColor, aHighColor, aShadeColor, aHighColor, aShadeColor };
			break;
		}
		case 5:
		case '5': {
			tColor = new int[] { aHighColor, aHighColor, aShadeColor, aHighColor, aShadeColor, aHighColor, aHighColor };
			break;
		}
		case 6:
		case '6': {
			tColor = new int[] { aHighColor, aHighColor, aShadeColor, aHighColor, aHighColor, aHighColor, aHighColor };
			break;
		}
		case 7:
		case '7': {
			tColor = new int[] { aHighColor, aShadeColor, aHighColor, aShadeColor, aShadeColor, aHighColor, aShadeColor };
			break;
		}
		case 8:
		case '8': {
			tColor = new int[] { aHighColor, aHighColor, aHighColor, aHighColor, aHighColor, aHighColor, aHighColor };
			break;
		}
		case 9:
		case '9': {
			tColor = new int[] { aHighColor, aHighColor, aHighColor, aHighColor, aShadeColor, aHighColor, aHighColor };
			break;
		}
		case '.': {
			tColor = new int[] { aHighColor };
			break;
		}
		case ':': {
			tColor = new int[] { aHighColor, aHighColor };
			break;
		}
		// Unknow word as 8
		default: {
			tColor = new int[] { aHighColor, aHighColor, aHighColor, aHighColor, aHighColor, aHighColor, aHighColor };
			break;
		}
		}

		int tWidth;
		Path tPath = new Path();
		Paint tPaint = new Paint();
		Canvas tCanvas = null;
		Bitmap tBitmap = null;

		tPaint.setStyle(Paint.Style.FILL);
		tPaint.setAntiAlias(true);
		tPaint.setFilterBitmap(true);

		if (tColor != null) {
			switch (tColor.length) {
			case 1: {
				tWidth = (int) (aHeight / 1.8f);

				tBitmap = Bitmap.createBitmap((int) (tWidth * 0.2), aHeight, Config.ARGB_4444);
				tCanvas = new Canvas(tBitmap);
				tCanvas.drawColor(aBackColor);

				tPaint.setColor(tColor[0]);
				tCanvas.drawRect(0, tWidth * 1.6f, tWidth * 0.2f, aHeight, tPaint);

				break;
			}
			case 2: {
				tWidth = (int) (aHeight / 1.8f);

				tBitmap = Bitmap.createBitmap((int) (tWidth * 0.2), aHeight, Config.ARGB_4444);
				tCanvas = new Canvas(tBitmap);
				tCanvas.drawColor(aBackColor);

				tPaint.setColor(tColor[0]);
				tPath.moveTo(tWidth * 0.1f, tWidth * 0.22828427f);
				tPath.moveTo(0, tWidth * 0.5f);
				tPath.moveTo(tWidth * 0.1f, tWidth * 0.77171573f);
				tPath.moveTo(tWidth * 0.2f, tWidth * 0.5f);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				tPaint.setColor(tColor[1]);
				tPath.reset();
				tPath.moveTo(tWidth * 0.1f, tWidth * 1.02828427f);
				tPath.moveTo(0, tWidth * 1.3f);
				tPath.moveTo(tWidth * 0.1f, tWidth * 1.57171573f);
				tPath.moveTo(tWidth * 0.2f, tWidth * 1.3f);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				break;
			}
			case 7: {
				tWidth = (int) (aHeight / 1.8f);

				tBitmap = Bitmap.createBitmap(tWidth, aHeight, Config.ARGB_4444);
				tCanvas = new Canvas(tBitmap);
				tCanvas.drawColor(aBackColor);

				tPaint.setColor(tColor[0]);
				tPath.moveTo(tWidth * 0.02828427f, 0);
				tPath.lineTo(tWidth * 0.22828427f, tWidth * 0.2f);
				tPath.lineTo(tWidth * 0.77171573f, tWidth * 0.2f);
				tPath.lineTo(tWidth * 0.97171573f, 0);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				tPaint.setColor(tColor[1]);
				tPath.reset();
				tPath.moveTo(0, tWidth * 0.02828427f);
				tPath.lineTo(0, tWidth * 0.8139807f);
				tPath.lineTo(tWidth * 0.1f, tWidth * 0.87171573f);
				tPath.lineTo(tWidth * 0.2f, tWidth * 0.77171573f);
				tPath.lineTo(tWidth * 0.2f, tWidth * 0.22828427f);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				tPaint.setColor(tColor[2]);
				tPath.reset();
				tPath.moveTo(tWidth * 0.8f, tWidth * 0.22828427f);
				tPath.lineTo(tWidth * 0.8f, tWidth * 0.77171573f);
				tPath.lineTo(tWidth * 0.9f, tWidth * 0.87171573f);
				tPath.lineTo(tWidth, tWidth * 0.8139807f);
				tPath.lineTo(tWidth, tWidth * 0.02828427f);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				tPaint.setColor(tColor[3]);
				tPath.reset();
				tPath.moveTo(tWidth * 0.12828427f, tWidth * 0.9f);
				tPath.lineTo(tWidth * 0.22828427f, tWidth);
				tPath.lineTo(tWidth * 0.77171573f, tWidth);
				tPath.lineTo(tWidth * 0.87171573f, tWidth * 0.9f);
				tPath.lineTo(tWidth * 0.77171573f, tWidth * 0.8f);
				tPath.lineTo(tWidth * 0.22828427f, tWidth * 0.8f);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				tPaint.setColor(tColor[4]);
				tPath.reset();
				tPath.moveTo(0, tWidth * 0.9860193f);
				tPath.lineTo(0, tWidth * 1.77171573f);
				tPath.lineTo(tWidth * 0.2f, tWidth * 1.57171573f);
				tPath.lineTo(tWidth * 0.2f, tWidth * 1.02828427f);
				tPath.lineTo(tWidth * 0.1f, tWidth * 0.92828427f);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				tPaint.setColor(tColor[5]);
				tPath.reset();
				tPath.moveTo(tWidth * 0.8f, tWidth * 1.02828427f);
				tPath.lineTo(tWidth * 0.8f, tWidth * 1.57171573f);
				tPath.lineTo(tWidth, tWidth * 1.77171573f);
				tPath.lineTo(tWidth, tWidth * 0.9860193f);
				tPath.lineTo(tWidth * 0.9f, tWidth * 0.92929427f);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				tPaint.setColor(tColor[6]);
				tPath.reset();
				tPath.moveTo(tWidth * 0.02828427f, aHeight);
				tPath.lineTo(tWidth * 0.97171573f, aHeight);
				tPath.lineTo(tWidth * 0.77171573f, tWidth * 1.6f);
				tPath.lineTo(tWidth * 0.22828427f, tWidth * 1.6f);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				break;
			}
			}

			if (tCanvas != null) {
				tCanvas.save();
				tCanvas.restore();

				return tBitmap;
			}
		}

		return null;
	}

	public static Bitmap GetDigitalString(String aWord, int aHeight, int aHighColor, int aShadeColor, int aBackColor) {
		if (aWord != null) {
			if (aWord.length() > 0) {
				if (aWord.length() == 1) {
					return GetDigitalWord(aWord.charAt(0), aHeight, aHighColor, aShadeColor, aBackColor);
				} else {
					int tWidth = 0;
					int tSpace = aHeight / 9;
					char tChars[] = aWord.toCharArray();
					ArrayList<Bitmap> tString = new ArrayList<Bitmap>();

					for (int i = 0; i < tChars.length; i++) {
						Bitmap tBitmap = GetDigitalWord(tChars[i], aHeight, aHighColor, aShadeColor, aBackColor);

						if (tBitmap != null) {
							tWidth += tBitmap.getWidth() + (i == tChars.length - 1 ? 0 : tSpace);
							tString.add(tBitmap);
						}
					}

					Bitmap tBitmap = Bitmap.createBitmap(tWidth, aHeight, Config.ARGB_4444);
					Canvas tCanvas = new Canvas(tBitmap);
					Paint tPaint = new Paint();
					int tLeft = 0;

					tPaint.setAntiAlias(true);
					tPaint.setFilterBitmap(true);

					tCanvas.drawColor(aBackColor);

					for (int i = 0; i < tString.size(); i++) {
						Bitmap tWord = tString.get(i);

						tCanvas.drawBitmap(tWord, null, new Rect(tLeft, 0, tLeft + tWord.getWidth(), tWord.getHeight()), tPaint);

						tLeft += tWord.getWidth() + tSpace;
					}

					tCanvas.save();
					tCanvas.restore();

					return tBitmap;
				}
			}
		}

		return null;
	}

	public static Bitmap GetSignlLevel(int aLevel, int aHeight, int aHighColor, int aShadeColor, int aBackColor) {
		int tColor[];

		/*if (aLevel > 0.75f){
			tColor = new int[]{aHighColor, aHighColor, aHighColor, aHighColor};
		}else if (aLevel > 0.5f){
			tColor = new int[]{aHighColor, aHighColor, aHighColor, aShadeColor};
		}else if (aLevel > 0.25f){
			tColor = new int[]{aHighColor, aHighColor, aShadeColor, aShadeColor};
		}else if (aLevel > 0){
			tColor = new int[]{aHighColor, aShadeColor, aShadeColor, aShadeColor};
		}else{
			tColor = new int[]{aShadeColor, aShadeColor, aShadeColor, aShadeColor};
		}*/

		if (aLevel == 3) {
			tColor = new int[] { aHighColor, aHighColor, aHighColor };
		} else if (aLevel == 2) {
			tColor = new int[] { aHighColor, aHighColor, aShadeColor };
		} else if (aLevel == 1) {
			tColor = new int[] { aHighColor, aShadeColor, aShadeColor };
		} else {
			tColor = new int[] { aShadeColor, aShadeColor, aShadeColor };
		}

		int tWidth;
		Paint tPaint = new Paint();
		Canvas tCanvas = null;
		Bitmap tBitmap = null;

		tPaint.setStyle(Paint.Style.FILL);
		tPaint.setAntiAlias(true);
		tPaint.setFilterBitmap(true);

		if (tColor != null) {
			switch (tColor.length) {
			case 4:
				tWidth = aHeight * 2;

				tBitmap = Bitmap.createBitmap(tWidth, aHeight, Config.ARGB_4444);
				tCanvas = new Canvas(tBitmap);
				tCanvas.drawColor(aBackColor);

				tPaint.setColor(tColor[0]);
				tCanvas.drawRect(0, aHeight * 0.75f, aHeight * 0.4f, aHeight, tPaint);

				tPaint.setColor(tColor[1]);
				tCanvas.drawRect(aHeight * 0.5334f, aHeight * 0.5f, aHeight * 0.9334f, aHeight, tPaint);

				tPaint.setColor(tColor[2]);
				tCanvas.drawRect(aHeight * 1.0668f, aHeight * 0.25f, aHeight * 1.4668f, aHeight, tPaint);

				tPaint.setColor(tColor[3]);
				tCanvas.drawRect(aHeight * 1.6f, 0, aHeight * 2f, aHeight, tPaint);
				break;
			case 3:
				tWidth = aHeight/2*3;

				tBitmap = Bitmap.createBitmap(tWidth, aHeight, Config.ARGB_4444);
				tCanvas = new Canvas(tBitmap);
				tCanvas.drawColor(aBackColor);

				tPaint.setColor(tColor[0]);
				tCanvas.drawRect(0, aHeight * 0.75f, aHeight * 0.4f, aHeight, tPaint);

				tPaint.setColor(tColor[1]);
				tCanvas.drawRect(aHeight * 0.5334f, aHeight * 0.5f, aHeight * 0.9334f, aHeight, tPaint);

				tPaint.setColor(tColor[2]);
				tCanvas.drawRect(aHeight * 1.0668f, aHeight * 0.25f, aHeight * 1.4668f, aHeight, tPaint);

				break;
			}

			if (tCanvas != null) {
				tCanvas.save();
				tCanvas.restore();

				return tBitmap;
			}
		}

		return null;
	}

	private static HashMap<String, Bitmap> gCPLogos = null;

	public synchronized static Bitmap GetCPLogo(int aWidth, int aHeight, int aBackGround) {
		String tKey = aWidth + "," + aHeight + "," + aBackGround;
		Bitmap tLogo = null;

		if (gCPLogos != null) {
			if (gCPLogos.containsKey(tKey)) {
				tLogo = gCPLogos.get(tKey);
			}
		}

		if (tLogo == null) {
			Canvas tCanvas;
			int tWidth = aWidth;
			int tHeight = (int) (aWidth * 0.5595689726f);
			float tDX = 0, tDY = 0;
			Path tPath = new Path();
			Paint tPaint = new Paint();

			try {
				if (aHeight < tHeight) {
					tWidth = (int) (aHeight / 0.5595689726f);
					tHeight = aHeight;
					tDX = (aWidth - tWidth) / 2;
				} else {
					tDY = (aHeight - tHeight) / 2;
				}

				tLogo = Bitmap.createBitmap(aWidth, aHeight, Config.ARGB_4444);

				tCanvas = new Canvas(tLogo);
				tCanvas.translate(tDX, tDY);
				tCanvas.drawColor(aBackGround);

				tPaint.setStyle(Paint.Style.FILL);
				tPaint.setAntiAlias(true);
				tPaint.setFilterBitmap(true);

				/*Left*/
				tPaint.setColor(Color.rgb(106, 23, 67));

				tPath.moveTo(tWidth * 0.4586701600f, tWidth * 0.0646583035f);
				tPath.arcTo(new RectF(0, 0, tHeight, tHeight), 310, -258);
				tPath.lineTo(tWidth * 0.4228940523f, tWidth * 0.4439126080f);
				tPath.arcTo(new RectF(tWidth * 0.0620346212f, tWidth * 0.0620346212f, tWidth * 0.4975421227f, tWidth * 0.4975421227f), 49, 263);
				tPath.close();
				tCanvas.drawPath(tPath, tPaint);

				/*Right*/
				tPaint.setColor(Color.rgb(158, 168, 177));
				tPath.reset();
				tPath.moveTo(tWidth * 0.3299967229f, tWidth * 0.3918783989f);
				tPath.lineTo(tWidth * 0.3812516230f, tWidth * 0.4209226432f);
				tPath.lineTo(tWidth * 0.5330690348f, tWidth * 0.1698997457f);
				tPath.arcTo(new RectF(tWidth * 0.5038775000f, tWidth * 0.0620346212f, tWidth * 0.9386924135f, tWidth * 0.4961225000f), 210, 313);
				tPath.lineTo(tWidth * 0.4737419657f, tWidth * 0.4067952637f);
				tPath.arcTo(new RectF(tWidth * 0.4425699136f, 0, tWidth, tHeight), 153, -293);
				tPath.close();

				tCanvas.drawPath(tPath, tPaint);

				tCanvas.save();
				tCanvas.restore();

				if (gCPLogos == null) {
					gCPLogos = new HashMap<String, Bitmap>();
				}

				gCPLogos.put(tKey, tLogo);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return tLogo;
	}

	public static Bitmap getArcProgress(float aWidth, float aHeight, float aLineWidth, int aBackColor, int aLineColor, float aProgress) {
		Bitmap tBitmap = null;
		Canvas tCanvas;
		Path tPath = new Path();
		Paint tPaint = new Paint();
		float tStartAngle = -90 + (360 * aProgress);

		try {
			tBitmap = Bitmap.createBitmap((int) aWidth, (int) aHeight, Config.ARGB_4444);

			tCanvas = new Canvas(tBitmap);
			tCanvas.drawColor(aBackColor);

			tPaint.setColor(aLineColor);
			tPaint.setStyle(Paint.Style.STROKE);

			tPaint.setStrokeWidth(aLineWidth);
			tCanvas.translate(aLineWidth / 2, aLineWidth / 2);

			tPaint.setAntiAlias(true);
			tPaint.setFilterBitmap(true);

			aWidth -= aLineWidth;
			aHeight -= aLineWidth;

			tPath.arcTo(new RectF(0, 0, aWidth, aHeight), tStartAngle, 360 - (360 * aProgress));

			tCanvas.drawPath(tPath, tPaint);

			tCanvas.save();
			tCanvas.restore();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return tBitmap;
	}

}
